// https://leetcode.cn/problems/fruit-into-baskets/

// 题干：你正在探访一家农场，农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示，其中 fruits[i] 是第 i 棵树上的水果 种类 。
//      你想要尽可能多地收集水果。然而，农场的主人设定了一些严格的规矩，你必须按照要求采摘水果：
//      你只有 两个 篮子，并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
//      你可以选择任意一棵树开始采摘，你必须从 每棵 树（包括开始采摘的树）上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。
//      每采摘一次，你将会向右移动到下一棵树，并继续采摘。
//      一旦你走到某棵树前，但水果不符合篮子的水果类型，那么就必须停止采摘。
//      给你一个整数数组 fruits ，返回你可以收集的水果的 最大 数目。

// 示例：输入：fruits = [1,2,1]
//       输出：3

// 碎语：解析题目，发现不过是找到一个含有不超过两个不同元素的最长子串
//       0 <= fruits[i] < fruits.length，即水果种类少于等于树的棵数
//       我们发现，当窗口里的元素种类大于两种的时候，此时right向右已经无意义，left右移
//       并且，right，没必要移动到与left同个位置，保留在原位置即可
//       也就是说，left和right同时向右移动，滑动窗口就成为了答案，元素种类的个数也就成为了判断的条件

#include <bits/stdc++.h>
using namespace std;

class Solution
{
public:
    int totalFruit(vector<int>& fruits)
    {
        int left = 0, right = 0, kind = 0;
        int hash[100000] = {0};
        int ret = 0;

        while (right < fruits.size()){
            kind += hash[fruits[right]] == 0 ? 1 : 0;
            hash[fruits[right]]++;

            while (kind > 2){
                hash[fruits[left]]--;
                kind -= hash[fruits[left]] == 0 ? 1 : 0;
                left++;
            }
            ret = max(ret, right - left + 1);
            right++;
        }

        return ret;
    }
};

int main()
{
    Solution sol;
    vector<int> fruits = {1,2,1};

    cout << sol.totalFruit(fruits) << endl;

    return 0;
}